{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Quantum Development Kit Samples<br>Diagnostics: Visualizing Quantum Programs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preamble"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll first open the [Microsoft.Quantum.Diagnostics namespace](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.diagnostics) so that its functions and operations are available throughout the notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "[]",
      "text/html": [
       "<ul></ul>"
      ],
      "text/plain": []
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "open Microsoft.Quantum.Diagnostics;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## What is a quantum program?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quantum programs are really **classical programs** that can send instructions to and get measurement results back from simulators and quantum devices."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As an example of this, **Q#** is a classical language designed to make it easier to write, test, and run quantum programs:\n",
    "\n",
    "- High-level\n",
    "- Focused on algorithms\n",
    "- Portable across simulators and hardware\n",
    "- Quantum-focused features\n",
    "- Diagnostics to help test and understand\n",
    "\n",
    "Q# is part of the **Microsoft Quantum Development Kit (QDK)**: [aka.ms/get-started-qdk](https://aka.ms/get-started-qdk)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Why is visualization important for quantum programs?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When running algorithms on quantum hardware, we **cannot observe the quantum state** prior to measurement.\n",
    "\n",
    "Even when running in a simulator, it may be **hard to gain intuition about the state** purely from wavefunction amplitudes."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Visualization helps with intuition** and may make it easier to:\n",
    "- understand the behavior of a quantum algorithm\n",
    "- identify bugs in its implementation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example: Teleportation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Quantum teleportation** is a textbook example of a simple quantum algorithm.\n",
    "\n",
    "It uses **entanglement and measurements** to \"teleport\" the exact quantum state of a source qubit to a target qubit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's use this algorithm to demonstrate a number of visualization techniques provided by Q# and the QDK:\n",
    "\n",
    "   - visualizing quantum **operations**\n",
    "   - visualizing quantum **states**\n",
    "   - visualizing an **execution path** for a quantum algorithm\n",
    "   - visualizing the **step-by-step operation** of a quantum program"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizing a Q# operation using `DumpOperation`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We begin by **defining a Q# operation** called `PrepareEntangledState`.\n",
    "\n",
    "We can **visualize this operation as a unitary matrix** by using `DumpOperation`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "[\"PrepareEntangledState\",\"VisualizePrepareEntangledState\"]",
      "text/html": [
       "<ul><li>PrepareEntangledState</li><li>VisualizePrepareEntangledState</li></ul>"
      ],
      "text/plain": [
       "PrepareEntangledState, VisualizePrepareEntangledState"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "operation PrepareEntangledState(qubits : Qubit[]) : Unit is Adj {\n",
    "    H(qubits[0]);\n",
    "    CNOT(qubits[0], qubits[1]);\n",
    "}\n",
    "\n",
    "operation VisualizePrepareEntangledState() : Unit {\n",
    "    DumpOperation(2, PrepareEntangledState);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\r\n",
       "                    <table>\r\n",
       "                        <tr>\r\n",
       "                            <th>Qubit IDs</th>\r\n",
       "                            <td>2, 3\r\n",
       "                        </tr>\r\n",
       "\r\n",
       "                        <tr>\r\n",
       "                            <th>Unitary representation</th>\r\n",
       "                            <td>$$\r\n",
       "                                \\left(\\begin{matrix}\r\n",
       "                                    0.707 & 0.707 & 0 & 0 \\\\\n",
       "0 & 0 & 0.707 & -0.707 \\\\\n",
       "0 & 0 & 0.707 & 0.707 \\\\\n",
       "0.707 & -0.707 & 0 & 0\r\n",
       "                                \\end{matrix}\\right)\r\n",
       "                            $$</td>\r\n",
       "                        </tr>\r\n",
       "                    </table>\r\n",
       "                "
      ],
      "text/plain": [
       "Real:\n",
       "[[0.7071067811865477, 0.7071067811865477, 0, 0], \r\n",
       "[0, 0, 0.7071067811865477, -0.7071067811865477], \r\n",
       "[0, 0, 0.7071067811865477, 0.7071067811865477], \r\n",
       "[0.7071067811865477, -0.7071067811865477, 0, 0]]\n",
       "Imag:\n",
       "[[0, 0, 0, 0], \r\n",
       "[0, 0, 0, 0], \r\n",
       "[0, 0, 0, 0], \r\n",
       "[0, 0, 0, 0]]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/json": "{\"@type\":\"tuple\"}",
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%simulate VisualizePrepareEntangledState"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizing quantum states within `Teleport` using `DumpRegister`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "[\"Teleport\"]",
      "text/html": [
       "<ul><li>Teleport</li></ul>"
      ],
      "text/plain": [
       "Teleport"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "open Microsoft.Quantum.Math;\n",
    "open Microsoft.Quantum.Random;\n",
    "\n",
    "operation Teleport() : Unit {\n",
    "    use source = Qubit();\n",
    "    use intermediate = Qubit();\n",
    "    use target = Qubit();\n",
    "\n",
    "    // Store a random message in the source qubit and visualize its state.\n",
    "    let randomAngle = DrawRandomDouble(0.0, 2.0*PI());\n",
    "    Rx(randomAngle, source);\n",
    "    Message(\"State of source qubit:\");\n",
    "    DumpRegister((), [source]);\n",
    "\n",
    "    // Create some entanglement that we can use to send our message.\n",
    "    PrepareEntangledState([intermediate, target]);\n",
    "\n",
    "    // Entangle the source qubit with the intermediate qubit.\n",
    "    CNOT(source, intermediate);\n",
    "    H(source);\n",
    "\n",
    "    // Measure the qubits and decode the message by applying corrections on the target qubit.\n",
    "    if (M(source) == One) { Z(target); }\n",
    "    if (M(intermediate) == One) { X(target); }\n",
    "\n",
    "    // Visualize the current state of the target qubit.\n",
    "    Message(\"State of target qubit:\");\n",
    "    DumpRegister((), [target]);\n",
    "    Reset(target);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we now simulate the `Teleport` operation, we can **verify that the quantum state is teleported correctly** each time it is run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "State of source qubit:\r\n"
     ]
    },
    {
     "data": {
      "application/json": "{\"div_id\":\"dump-machine-div-1c46427a-c4c3-4607-b546-b4acde81a77b\",\"qubit_ids\":[0],\"n_qubits\":1,\"amplitudes\":[{\"Real\":0.11516358063443338,\"Imaginary\":0.0,\"Magnitude\":0.11516358063443338,\"Phase\":0.0},{\"Real\":0.0,\"Imaginary\":-0.9933465405866456,\"Magnitude\":0.9933465405866456,\"Phase\":-1.5707963267948966}]}",
      "text/html": [
       "\r\n",
       "                    <table style=\"table-layout: fixed; width: 100%\">\r\n",
       "                        <thead>\r\n",
       "                            \r\n",
       "                        <tr>\r\n",
       "                            <th>Qubit IDs</th>\r\n",
       "                            <td span=\"3\">0</td>\r\n",
       "                        </tr>\r\n",
       "                    \r\n",
       "                            <tr>\r\n",
       "                                <th style=\"width: 20ch)\">Basis state (little endian)</th>\r\n",
       "                                <th style=\"width: 20ch\">Amplitude</th><th style=\"width: calc(100% - 26ch - 20ch)\">Meas. Pr.</th><th style=\"width: 6ch\">Phase</th>\r\n",
       "                            </tr>\r\n",
       "                        </thead>\r\n",
       "                        <tbody>\r\n",
       "                        \r\n",
       "                            <tr>\r\n",
       "                                <td>$\\left|0\\right\\rangle$</td>\r\n",
       "                                <td>$0.1152 + 0.0000 i$</td>\r\n",
       "                                \r\n",
       "                                <td>\r\n",
       "                                    <progress\r\n",
       "                                        max=\"100\"\r\n",
       "                                        value=\"1.326265030454364\"\r\n",
       "                                        style=\"width: 100%;\"\r\n",
       "                                    > \r\n",
       "                                    <td>\r\n",
       "                                    <p id=\"round-209f0a91-7635-4af9-949c-25e9ff889127\"> \r\n",
       "                                    <script>\r\n",
       "                                    var num = 1.326265030454364;\r\n",
       "                                    num = num.toFixed(4);\r\n",
       "                                    var num_string = num + \"%\";\r\n",
       "                                     document.getElementById(\"round-209f0a91-7635-4af9-949c-25e9ff889127\").innerHTML = num_string;\r\n",
       "                                    </script> </p>\r\n",
       "                                    </td>\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                                \r\n",
       "                                <td style=\"transform: rotate(0deg);\r\n",
       "                   text-align: center;\">\r\n",
       "                                 ↑\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                            </tr>\r\n",
       "                        \n",
       "\r\n",
       "                            <tr>\r\n",
       "                                <td>$\\left|1\\right\\rangle$</td>\r\n",
       "                                <td>$0.0000  -0.9933 i$</td>\r\n",
       "                                \r\n",
       "                                <td>\r\n",
       "                                    <progress\r\n",
       "                                        max=\"100\"\r\n",
       "                                        value=\"98.67373496954563\"\r\n",
       "                                        style=\"width: 100%;\"\r\n",
       "                                    > \r\n",
       "                                    <td>\r\n",
       "                                    <p id=\"round-024cb0e6-8b3e-48ea-864d-728751642d6c\"> \r\n",
       "                                    <script>\r\n",
       "                                    var num = 98.67373496954563;\r\n",
       "                                    num = num.toFixed(4);\r\n",
       "                                    var num_string = num + \"%\";\r\n",
       "                                     document.getElementById(\"round-024cb0e6-8b3e-48ea-864d-728751642d6c\").innerHTML = num_string;\r\n",
       "                                    </script> </p>\r\n",
       "                                    </td>\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                                \r\n",
       "                                <td style=\"transform: rotate(-90deg);\r\n",
       "                   text-align: center;\">\r\n",
       "                                 ↑\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                            </tr>\r\n",
       "                        \r\n",
       "                        </tbody>\r\n",
       "                    </table>"
      ],
      "text/plain": [
       "|0⟩\t0.11516358063443338 + 0𝑖\n",
       "|1⟩\t0 + -0.9933465405866456𝑖"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "State of target qubit:\r\n"
     ]
    },
    {
     "data": {
      "application/json": "{\"div_id\":\"dump-machine-div-c829cac9-9429-45fc-927a-acda3617191e\",\"qubit_ids\":[2],\"n_qubits\":1,\"amplitudes\":[{\"Real\":0.11516358063443337,\"Imaginary\":0.0,\"Magnitude\":0.11516358063443337,\"Phase\":0.0},{\"Real\":0.0,\"Imaginary\":-0.9933465405866456,\"Magnitude\":0.9933465405866456,\"Phase\":-1.5707963267948966}]}",
      "text/html": [
       "\r\n",
       "                    <table style=\"table-layout: fixed; width: 100%\">\r\n",
       "                        <thead>\r\n",
       "                            \r\n",
       "                        <tr>\r\n",
       "                            <th>Qubit IDs</th>\r\n",
       "                            <td span=\"3\">2</td>\r\n",
       "                        </tr>\r\n",
       "                    \r\n",
       "                            <tr>\r\n",
       "                                <th style=\"width: 20ch)\">Basis state (little endian)</th>\r\n",
       "                                <th style=\"width: 20ch\">Amplitude</th><th style=\"width: calc(100% - 26ch - 20ch)\">Meas. Pr.</th><th style=\"width: 6ch\">Phase</th>\r\n",
       "                            </tr>\r\n",
       "                        </thead>\r\n",
       "                        <tbody>\r\n",
       "                        \r\n",
       "                            <tr>\r\n",
       "                                <td>$\\left|0\\right\\rangle$</td>\r\n",
       "                                <td>$0.1152 + 0.0000 i$</td>\r\n",
       "                                \r\n",
       "                                <td>\r\n",
       "                                    <progress\r\n",
       "                                        max=\"100\"\r\n",
       "                                        value=\"1.3262650304543635\"\r\n",
       "                                        style=\"width: 100%;\"\r\n",
       "                                    > \r\n",
       "                                    <td>\r\n",
       "                                    <p id=\"round-ab40bf3b-2cdd-4357-95ac-0a35781fcb08\"> \r\n",
       "                                    <script>\r\n",
       "                                    var num = 1.3262650304543635;\r\n",
       "                                    num = num.toFixed(4);\r\n",
       "                                    var num_string = num + \"%\";\r\n",
       "                                     document.getElementById(\"round-ab40bf3b-2cdd-4357-95ac-0a35781fcb08\").innerHTML = num_string;\r\n",
       "                                    </script> </p>\r\n",
       "                                    </td>\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                                \r\n",
       "                                <td style=\"transform: rotate(0deg);\r\n",
       "                   text-align: center;\">\r\n",
       "                                 ↑\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                            </tr>\r\n",
       "                        \n",
       "\r\n",
       "                            <tr>\r\n",
       "                                <td>$\\left|1\\right\\rangle$</td>\r\n",
       "                                <td>$0.0000  -0.9933 i$</td>\r\n",
       "                                \r\n",
       "                                <td>\r\n",
       "                                    <progress\r\n",
       "                                        max=\"100\"\r\n",
       "                                        value=\"98.67373496954563\"\r\n",
       "                                        style=\"width: 100%;\"\r\n",
       "                                    > \r\n",
       "                                    <td>\r\n",
       "                                    <p id=\"round-5fd155f5-9c2e-4cb0-b601-067519bef4c6\"> \r\n",
       "                                    <script>\r\n",
       "                                    var num = 98.67373496954563;\r\n",
       "                                    num = num.toFixed(4);\r\n",
       "                                    var num_string = num + \"%\";\r\n",
       "                                     document.getElementById(\"round-5fd155f5-9c2e-4cb0-b601-067519bef4c6\").innerHTML = num_string;\r\n",
       "                                    </script> </p>\r\n",
       "                                    </td>\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                                \r\n",
       "                                <td style=\"transform: rotate(-90deg);\r\n",
       "                   text-align: center;\">\r\n",
       "                                 ↑\r\n",
       "                                </td>\r\n",
       "                            \r\n",
       "                            </tr>\r\n",
       "                        \r\n",
       "                        </tbody>\r\n",
       "                    </table>"
      ],
      "text/plain": [
       "|0⟩\t0.11516358063443337 + 0𝑖\n",
       "|1⟩\t0 + -0.9933465405866456𝑖"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/json": "{\"@type\":\"tuple\"}",
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%simulate Teleport"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizing an execution path of a Q# operation with `%trace`\n",
    "\n",
    "- Q# operations may consist of **complex programming paradigms** (e.g. recursion, loops)\n",
    "- **Hard to represent** as a quantum circuit\n",
    "- Visualize an **execution path** instead!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For a simple program, the execution path looks exactly like a circuit:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "[\"MeasureEntangledState\"]",
      "text/html": [
       "<ul><li>MeasureEntangledState</li></ul>"
      ],
      "text/plain": [
       "MeasureEntangledState"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "operation MeasureEntangledState() : Result[] {\n",
    "    use qubits = Qubit[2];\n",
    "    H(qubits[0]);\n",
    "    CNOT(qubits[0], qubits[1]);\n",
    "    return [M(qubits[0]), M(qubits[1])];\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='execution-path-container-d0faa08a-9e2d-4b79-a56c-9da12669649a' />\"}",
      "text/html": [
       "<div id='execution-path-container-d0faa08a-9e2d-4b79-a56c-9da12669649a' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%trace MeasureEntangledState"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Complex programs are **modular** and will likely contain **nested operations**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "[\"MeasureEntangledStateModular\"]",
      "text/html": [
       "<ul><li>MeasureEntangledStateModular</li></ul>"
      ],
      "text/plain": [
       "MeasureEntangledStateModular"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "open Microsoft.Quantum.Arrays;\n",
    "\n",
    "operation MeasureEntangledStateModular() : Result[] {\n",
    "    use qubits = Qubit[2];\n",
    "    PrepareEntangledState(qubits);\n",
    "    return ForEach(M, qubits);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With `%trace`, we can visualize the program at a high level and **zoom in** to each operation as desired:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='execution-path-container-7af33e02-581c-4c61-896b-632592b72720' />\"}",
      "text/html": [
       "<div id='execution-path-container-7af33e02-581c-4c61-896b-632592b72720' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%trace MeasureEntangledStateModular"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Execution paths are non-deterministic!\n",
    "\n",
    "For example, an operation that uses a **\"repeat-until-success\" loop** may have very different execution paths depending on measurement results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "[\"MeasureUntilOne\"]",
      "text/html": [
       "<ul><li>MeasureUntilOne</li></ul>"
      ],
      "text/plain": [
       "MeasureUntilOne"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "operation MeasureUntilOne() : Unit {\n",
    "    mutable result = Zero;\n",
    "    use q = Qubit();\n",
    "    repeat {\n",
    "        H(q);\n",
    "        set result = M(q);\n",
    "    }\n",
    "    until result == One;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='execution-path-container-7b4ddacf-c96f-4474-9458-04cd00f46776' />\"}",
      "text/html": [
       "<div id='execution-path-container-7b4ddacf-c96f-4474-9458-04cd00f46776' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%trace MeasureUntilOne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualizing an execution path for `Teleport`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The execution path for `Teleport` will differ based on the results of the two measurements.\n",
    "\n",
    "By repeating `%trace`, we see that the `X` and `Z` operations **only sometimes occur** on the target qubit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='execution-path-container-9129bb70-b80a-4a88-9c5a-090ffdcc6e13' />\"}",
      "text/html": [
       "<div id='execution-path-container-9129bb70-b80a-4a88-9c5a-090ffdcc6e13' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%trace Teleport"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stepping through a Q# operation with `%debug`\n",
    "\n",
    "- Classical programming tools typically have **debuggers**, which run one line of code at a time and allow inspection of variable state at each step.\n",
    "- For small Q# programs, the `%debug` command allows one to **observe how the quantum state changes** as a quantum program runs."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we step through an operation that **prepares and measures an entangled state**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting debug session for MeasureEntangledState...\r\n"
     ]
    },
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='b324adfd-33c3-4f23-afc8-8d97f2beaa32' />\"}",
      "text/html": [
       "<div id='b324adfd-33c3-4f23-afc8-8d97f2beaa32' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='execution-path-container-2b4e2952-daf1-402d-8314-697f1b542d10' />\"}",
      "text/html": [
       "<div id='execution-path-container-2b4e2952-daf1-402d-8314-697f1b542d10' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Finished debug session for MeasureEntangledState.\r\n"
     ]
    },
    {
     "data": {
      "application/json": "[1,1]",
      "text/html": [
       "<ul><li>One</li><li>One</li></ul>"
      ],
      "text/plain": [
       "One, One"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%debug MeasureEntangledState"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stepping through `Teleport`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we step through the `Teleport` operation, which tracks the quantum state of all three qubits:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting debug session for Teleport...\r\n"
     ]
    },
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='1e36b7fa-5b93-4a04-a0b9-0715f3b51785' />\"}",
      "text/html": [
       "<div id='1e36b7fa-5b93-4a04-a0b9-0715f3b51785' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/json": "{\"Html\":\"<div id='execution-path-container-e5a5caaa-bd83-4787-bde8-8a977417d2bf' />\"}",
      "text/html": [
       "<div id='execution-path-container-e5a5caaa-bd83-4787-bde8-8a977417d2bf' />"
      ],
      "text/plain": [
       "Microsoft.Quantum.IQSharp.Jupyter.DisplayableHtmlElement"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Finished debug session for Teleport.\r\n"
     ]
    },
    {
     "data": {
      "application/json": "{\"@type\":\"tuple\"}",
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%debug Teleport"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have demonstrated several visualization techniques provided by Q# and the QDK:\n",
    "\n",
    "   - visualizing quantum **operations**\n",
    "   - visualizing quantum **states**\n",
    "   - visualizing an **execution path** for a quantum algorithm\n",
    "   - visualizing the **step-by-step operation** of a quantum program\n",
    "\n",
    "A **variety of visualization tools** can be useful for quantum programs. Not one-size-fits-all!\n",
    "\n",
    "Visualization is an important way for students and researchers to **gain intuition** about quantum algorithms and **understand the operation** of quantum programs."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Epilogue"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/json": "{\"rows\":[{\"@type\":\"@tuple\",\"Item1\":\"iqsharp\",\"Item2\":\"0.15.2101125897\"},{\"@type\":\"@tuple\",\"Item1\":\"Jupyter Core\",\"Item2\":\"1.5.0.0\"},{\"@type\":\"@tuple\",\"Item1\":\".NET Runtime\",\"Item2\":\".NETCoreApp,Version=v3.1\"}]}",
      "text/html": [
       "<table><thead><tr><th style=\"text-align: start;\">Component</th><th style=\"text-align: start;\">Version</th></tr></thead><tbody><tr><td style=\"text-align: start;\">iqsharp</td><td style=\"text-align: start;\">0.15.2101125897</td></tr><tr><td style=\"text-align: start;\">Jupyter Core</td><td style=\"text-align: start;\">1.5.0.0</td></tr><tr><td style=\"text-align: start;\">.NET Runtime</td><td style=\"text-align: start;\">.NETCoreApp,Version=v3.1</td></tr></tbody></table>"
      ],
      "text/plain": [
       "Component    Version\r\n",
       "------------ ------------------------\r\n",
       "iqsharp      0.15.2101125897\r\n",
       "Jupyter Core 1.5.0.0\r\n",
       ".NET Runtime .NETCoreApp,Version=v3.1\r\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Q#",
   "language": "qsharp",
   "name": "iqsharp"
  },
  "language_info": {
   "file_extension": ".qs",
   "mimetype": "text/x-qsharp",
   "name": "qsharp",
   "version": "0.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
